<template>
  <div class="assign-container">
    <el-button type="primary" @click="openAssignDialog" size="small">
      <el-icon><UserFilled /></el-icon>
      分派漏洞
    </el-button>

    <!-- 分派漏洞对话框 -->
    <el-dialog
      title="分派漏洞"
      v-model="dialogVisible"
      width="500px"
    >
      <el-form :model="assignForm" :rules="rules" ref="assignFormRef" label-width="100px">
        <el-form-item label="分派给用户" prop="assigned_to_id">
          <el-select
            v-model="assignForm.assigned_to_id"
            placeholder="选择用户"
            filterable
            style="width: 100%"
          >
            <el-option
              v-for="user in users"
              :key="user.id"
              :label="user.real_name || user.username"
              :value="user.id"
            >
              <div class="user-option">
                <el-avatar :size="24" :src="user.avatar">{{ user.username.substring(0, 1).toUpperCase() }}</el-avatar>
                <span style="margin-left: 8px">{{ user.real_name || user.username }}</span>
                <span style="color: #999; margin-left: 8px">({{ user.email }})</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item label="优先级" prop="priority">
          <el-select v-model="assignForm.priority" placeholder="选择优先级" style="width: 100%">
            <el-option :value="1" label="低">
              <el-tag type="info" size="small">低</el-tag>
            </el-option>
            <el-option :value="2" label="中低">
              <el-tag type="info" size="small">中低</el-tag>
            </el-option>
            <el-option :value="3" label="中">
              <el-tag type="warning" size="small">中</el-tag>
            </el-option>
            <el-option :value="4" label="中高">
              <el-tag type="warning" size="small">中高</el-tag>
            </el-option>
            <el-option :value="5" label="高">
              <el-tag type="danger" size="small">高</el-tag>
            </el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item label="截止日期" prop="due_date">
          <el-date-picker
            v-model="assignForm.due_date"
            type="date"
            placeholder="选择截止日期"
            style="width: 100%"
            :disabledDate="disabledDate"
            value-format="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
          />
        </el-form-item>
        
        <el-form-item label="备注" prop="notes">
          <el-input
            v-model="assignForm.notes"
            type="textarea"
            :rows="4"
            placeholder="添加备注信息"
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitAssign" :loading="loading">分派</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 分派历史列表 -->
    <div class="assignment-history" v-if="assignments.length > 0">
      <h3>分派历史</h3>
      <el-timeline>
        <el-timeline-item
          v-for="assignment in assignments"
          :key="assignment.id"
          :timestamp="formatDateTime(assignment.created_at)"
          :type="getTimelineType(assignment.status)"
        >
          <el-card shadow="hover">
            <template #header>
              <div class="assignment-header">
                <div>
                  <el-tag
                    :type="getStatusType(assignment.status)"
                    effect="dark"
                  >
                    {{ getStatusText(assignment.status) }}
                  </el-tag>
                  <span class="ml-2">分派给：{{ assignment.assigned_to?.real_name || assignment.assigned_to?.username }}</span>
                </div>
                <div>
                  <el-tag size="small" v-if="assignment.priority">
                    优先级 {{ getPriorityText(assignment.priority) }}
                  </el-tag>
                </div>
              </div>
            </template>
            <div class="assignment-content">
              <div v-if="assignment.notes">
                <div class="text-secondary">分派说明：</div>
                <p class="mt-1">{{ assignment.notes }}</p>
              </div>
              <div v-if="assignment.response" class="mt-2">
                <div class="text-secondary">处理反馈：</div>
                <p class="mt-1">{{ assignment.response }}</p>
              </div>
              <div class="mt-2">
                <span class="text-secondary">分派人：</span>
                <span>{{ assignment.assigned_by?.real_name || assignment.assigned_by?.username }}</span>
                <span class="mx-2">|</span>
                <span class="text-secondary">截止日期：</span>
                <span :class="{'text-danger': isOverdue(assignment.due_date)}">
                  {{ formatDate(assignment.due_date) }}
                  <el-tag v-if="isOverdue(assignment.due_date)" type="danger" size="small">已逾期</el-tag>
                </span>
              </div>
            </div>
          </el-card>
        </el-timeline-item>
      </el-timeline>
    </div>

    <!-- 错误信息对话框 -->
    <el-dialog
      title="请求错误详情"
      v-model="errorDialogVisible"
      width="800px"
    >
      <div v-if="errorDetails">
        <h4>错误信息</h4>
        <pre style="background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow: auto;">{{ JSON.stringify(errorDetails, null, 2) }}</pre>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted, defineProps, defineEmits } from 'vue'
import { UserFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { getUserList } from '@/api/user'
import { assignVulnerability, getVulnerabilityAssignments } from '@/api/assignment'

export default {
  name: 'AssignVulnerability',
  components: {
    UserFilled
  },
  props: {
    vulnerabilityId: {
      type: [Number, String],
      required: true
    }
  },
  emits: ['assigned'],
  setup(props, { emit }) {
    const dialogVisible = ref(false)
    const assignFormRef = ref(null)
    const loading = ref(false)
    const users = ref([])
    const assignments = ref([])
    
    // 错误处理相关
    const errorDialogVisible = ref(false)
    const errorDetails = ref(null)

    // 表单数据
    const assignForm = reactive({
      assigned_to_id: null,
      priority: 3, // 默认优先级为中
      due_date: '',
      notes: ''
    })

    // 表单验证规则
    const rules = {
      assigned_to_id: [{ required: true, message: '请选择分派用户', trigger: 'change' }],
      priority: [{ required: true, message: '请选择优先级', trigger: 'change' }],
      due_date: [{ required: true, message: '请选择截止日期', trigger: 'change' }]
    }

    // 禁止选择过去的日期
    const disabledDate = (time) => {
      return time.getTime() < Date.now() - 8.64e7 // 禁止选择今天之前的日期
    }

    // 获取用户列表
    const fetchUsers = async () => {
      try {
        const response = await getUserList()
        if (response.code === 200) {
          users.value = response.data
        }
      } catch (error) {
        console.error('获取用户列表失败:', error)
        ElMessage.error('获取用户列表失败')
      }
    }

    // 获取漏洞分派历史
    const fetchAssignments = async () => {
      try {
        const response = await getVulnerabilityAssignments(props.vulnerabilityId)
        if (response.code === 200) {
          assignments.value = response.data
        }
      } catch (error) {
        console.error('获取分派历史失败:', error)
      }
    }

    // 打开分派对话框
    const openAssignDialog = () => {
      dialogVisible.value = true
      // 初始化表单数据
      assignForm.assigned_to_id = null
      assignForm.priority = 3
      assignForm.due_date = formatDateString(new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)) // 默认一周后
      assignForm.notes = ''
    }

    // 提交分派
    const submitAssign = async () => {
      if (!assignFormRef.value) return
      
      await assignFormRef.value.validate(async (valid) => {
        if (!valid) return
        
        loading.value = true
        try {
          // 确保ID是数字
          const vulnId = parseInt(props.vulnerabilityId, 10);
          if (isNaN(vulnId)) {
            throw new Error('无效的漏洞ID');
          }
          
          // 准备提交数据
          const submitData = {
            ...assignForm
          };
          
          // 确保日期格式正确
          if (submitData.due_date && typeof submitData.due_date === 'string') {
            // 如果日期已经是字符串格式，确保它是有效的ISO格式
            try {
              const dateObj = new Date(submitData.due_date);
              submitData.due_date = dateObj.toISOString();
            } catch (e) {
              console.error('日期格式转换失败:', e);
            }
          }
          
          console.log('提交分派数据:', {
            vulnId,
            formData: submitData
          })
          
          const response = await assignVulnerability(vulnId, submitData)
          if (response.code === 200) {
            ElMessage.success('分派漏洞成功')
            dialogVisible.value = false
            await fetchAssignments() // 刷新分派历史
            emit('assigned')
          } else {
            ElMessage.error(response.message || '分派漏洞失败')
          }
        } catch (error) {
          console.error('分派漏洞失败:', error)
          console.error('错误详情:', error.response ? {
            status: error.response.status,
            statusText: error.response.statusText,
            data: error.response.data,
            headers: error.response.headers,
            config: error.response.config
          } : '无详细信息')
          ElMessage.error(`分派漏洞失败: ${error.message}`)
          errorDetails.value = error.response ? error.response.data : { message: error.message }
          errorDialogVisible.value = true
        } finally {
          loading.value = false
        }
      })
    }

    // 格式化日期
    const formatDate = (dateString) => {
      if (!dateString) return '未设置'
      const date = new Date(dateString)
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
    }

    // 格式化日期时间
    const formatDateTime = (dateString) => {
      if (!dateString) return ''
      const date = new Date(dateString)
      return `${formatDate(dateString)} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
    }

    // 格式化日期为字符串
    const formatDateString = (date) => {
      return date.toISOString()
    }

    // 判断是否逾期
    const isOverdue = (dateString) => {
      if (!dateString) return false
      const dueDate = new Date(dateString)
      return dueDate < new Date() && new Date(dateString).toDateString() !== new Date().toDateString()
    }

    // 获取状态对应的类型
    const getStatusType = (status) => {
      const types = {
        'pending': 'info',
        'accepted': 'success',
        'rejected': 'danger',
        'fixed': 'primary',
        'closed': 'warning'
      }
      return types[status] || 'info'
    }

    // 获取时间线类型
    const getTimelineType = (status) => {
      const types = {
        'pending': 'info',
        'accepted': 'success',
        'rejected': 'danger',
        'fixed': 'primary',
        'closed': 'warning'
      }
      return types[status] || 'info'
    }

    // 获取状态文本
    const getStatusText = (status) => {
      const texts = {
        'pending': '待处理',
        'accepted': '已接受',
        'rejected': '已拒绝',
        'fixed': '已修复',
        'closed': '已关闭'
      }
      return texts[status] || '未知状态'
    }

    // 获取优先级文本
    const getPriorityText = (priority) => {
      const texts = {
        1: '低',
        2: '中低',
        3: '中',
        4: '中高',
        5: '高'
      }
      return texts[priority] || '未知'
    }

    onMounted(() => {
      fetchUsers()
      fetchAssignments()
    })

    return {
      dialogVisible,
      assignFormRef,
      loading,
      users,
      assignments,
      assignForm,
      rules,
      disabledDate,
      openAssignDialog,
      submitAssign,
      formatDate,
      formatDateTime,
      isOverdue,
      getStatusType,
      getTimelineType,
      getStatusText,
      getPriorityText,
      errorDialogVisible,
      errorDetails
    }
  }
}
</script>

<style scoped>
.assign-container {
  margin-top: 20px;
}

.assignment-history {
  margin-top: 20px;
}

.assignment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.assignment-content {
  font-size: 14px;
}

.user-option {
  display: flex;
  align-items: center;
}

.ml-2 {
  margin-left: 8px;
}

.mt-1 {
  margin-top: 4px;
}

.mt-2 {
  margin-top: 8px;
}

.mx-2 {
  margin-left: 8px;
  margin-right: 8px;
}

.text-secondary {
  color: #606266;
}

.text-danger {
  color: #f56c6c;
}
</style> 